﻿
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using System;
using System.Net;
using XLAction.GlobalIPReqAction;

namespace XLAction
{
    public class BasicAuthAttribute : IAuthorizationFilter
    {
        public async void OnAuthorization(AuthorizationFilterContext context)
        {
            if (context.Filters.Contains(new MyNoAuthentication()))
            {
                return;
            }
            #region 用户请求限流
            {
                //获取客户端IP
                string ip = context.HttpContext.Connection.RemoteIpAddress.ToString();


                var cotrollaction = context.ActionDescriptor;
                //获取客户端请求接口方法
                string action = cotrollaction.RouteValues["action"].ToString();
                //获取客户端请求的控制器
                string controller = cotrollaction.RouteValues["controller"].ToString();

                #region 黑名单检查，可更改为白名单，
                //if (IsBlacklisted(IPAddress.Parse(ip).MapToIPv4()))
                //{
                //    // IP 在黑名单中，返回 403 Forbidden
                //    context.Result = new JsonResult("永久拒绝访问！") { StatusCode = StatusCodes.Status403Forbidden };
                //    return;
                //} 
                #endregion

                if (string.IsNullOrWhiteSpace(ip) || string.IsNullOrWhiteSpace(controller) || string.IsNullOrWhiteSpace(action))
                {
                   
                    context.Result = new JsonResult("系统正忙，请稍微再试！") { StatusCode = StatusCodes.Status429TooManyRequests };
                    return;
                }
                ip = ip + ":" + controller + ":" + action;
                IPCacheInfoModel ipModel = IPCacheHelper.GetIPLimitInfo(ip);
                if (!ipModel.IsVisit)
                {
                    int limit = Convert.ToInt32(GetConfigToJson.GetConfiguration("IPIimit", "GlobalIPConfig.json"));
                    //此处可将访问过多的ip设置为黑名单
                    if (ipModel.Limit>= limit)
                    {
                        //加入黑名单
                    }
                    //限流信息打印至控制台
                    Console.WriteLine((string.Format("IP【{0}】被限制了【{1}】次数", ipModel.IP, ipModel.Limit)));
                    context.Result = new JsonResult("系统正忙，请稍微再试！") { StatusCode = StatusCodes.Status429TooManyRequests };
                    return;
                }
            }
            #endregion

        }
        private bool IsBlacklisted(IPAddress ipAddress)
        {
            // 在此实现黑名单 IP 地址的逻辑，例如从配置文件或数据库中获取黑名单列表
            // 这里只是一个示例，您需要根据实际需求实现逻辑

            //此处示例黑名单，可将此改为白名单，可在appsettings.json文件中添加白名单
            //也可以新建json文件作为黑名单或白名单检查
            //如需要持久化，可采用Redis或者内存缓存IMemoryCache
            var blacklistedIPs = new List<IPAddress>
            {
                IPAddress.Parse("0.0.0.1"), // 示例黑名单IP
                // 添加其他黑名单IP
            };

            return blacklistedIPs.Contains(ipAddress);
        }
    }
}
